//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <ddk.h>

class MilliSecondsTicks : public CDeviceDriver
{
public:
    CARAPI Read(
        /* [in] */ UInt64 u64Offset,
        /* [in] */ UInt32 bytesToRead,
        /* [out] */ EzByteBuf buffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Write(
        /* [in] */ UInt64 u64Offset,
        /* [in] */ EzByteBuf buffer,
        /* [out] */ UInt32 * pBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ EzByteBuf inBuffer,
        /* [out] */ EzByteBuf * pOutBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    virtual void Dispose() {}
};

EXTERN IDeviceDriver * CDECL CreateMilliSecondsTicks(uint_t uDeviceNo,
    void *pvParameter)
{
    MilliSecondsTicks *pDriver = new MilliSecondsTicks;
    if (NULL == pDriver) {
        kprintf("ERROR:There have no enough memory, %s, %d\n",
                        __FILE__, __LINE__);
        return NULL;
    }

    pDriver->AddRef();

    return pDriver;
}

ECode MilliSecondsTicks::Read(
    /* [in] */ UInt64 u64Offset,
    /* [in] */ UInt32 bytesToRead,
    /* [out] */ EzByteBuf buffer,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    if (0 != u64Offset || NULL != ppCompletionEvent
        || (UInt32)buffer.GetCapacity() < sizeof(UInt32)) {
        return E_INVALID_ARGUMENT;
    }

    *(UInt32 *)(char *)buffer = DzMillisecondsToTicks(bytesToRead);
    buffer.SetUsed(sizeof(UInt32));

    return NOERROR;
}

ECode MilliSecondsTicks::Write(
    /* [in] */ UInt64 u64Offset,
    /* [in] */ EzByteBuf buffer,
    /* [out] */ UInt32 * pBytesWritten,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    if (0 != u64Offset || NULL != ppCompletionEvent
        || (UInt32)buffer.GetCapacity() < sizeof(UInt32)
        || NULL == pBytesWritten) {
        return E_INVALID_ARGUMENT;
    }

    *pBytesWritten =
        DzTicksToMilliseconds(*(uint_t *)(char *)buffer);

    return NOERROR;
}

ECode MilliSecondsTicks::Control(
    /* [in] */ Handle32 nControlCode,
    /* [in] */ EzByteBuf inBuffer,
    /* [out] */ EzByteBuf * pOutBuffer,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}
